﻿using System.Reflection;
using Autofac;
using Autofac.Extras.DynamicProxy;
using ManaSky.Autofac;
using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.Mvc.Controllers;

namespace ManaSky.Api.DI;

public class AutofacModule: InjectionModule
{
    protected override void Load(ContainerBuilder builder)
    {
        #region 生命周期
        //InstancePerLifetimeScope：同一个Lifetime(范围)生成的对象是同一个实例
        //SingleInstance：单例模式，每次调用，都会使用同一个实例化的对象；每次都用同一个对象；
        //InstancePerDependency：默认模式，每次调用，都会重新实例化对象；每次请求都创建一个新的对象
        // InstancePerMatchingLifetimeScope("name名称") *匹配 name* 声明周期范围实例
        //InstancePerRequest 每一个请求,一个实例
        #endregion

        #region 构造注入
        //AutoFac容器 默认支持构造函数注入
        //这里现在是构造注入 并且是单例模式
        //builder.RegisterType<TestService>().As<ITestService>().SingleInstance();
        #endregion
        
        #region Controller注册
        //如果要在控制类使用属性注入 要使用Autofac对Controller进行IOC注册，并开启使用PropertiesAutowired属性注入
        //这样在控制器内就可以使用属性注入了
        var controllerBaseType = typeof(ControllerBase);
        builder.RegisterAssemblyTypes(typeof(Program).Assembly)
            .Where(t => controllerBaseType.IsAssignableFrom(t) && t != controllerBaseType)
            .InstancePerLifetimeScope()
            .PropertiesAutowired();
        #endregion

        #region 属性注入
        //现在TestService内开启了属性注入,并且TestService是单例模式
        //builder.RegisterType<TestService>().As<ITestService>().PropertiesAutowired().SingleInstance(); 
        //builder.RegisterType<TestRepository>().As<ITestRepository>();
        #endregion
        
        #region 方法注入
        //builder.RegisterType<TestRepository>().As<ITestRepository>();
        //builder.RegisterType<TestService>().OnActivated(a => a.Instance.SetTestRepository(a.Context.Resolve<ITestRepository>())).As<ITestService>();
        #endregion
        //这里是用于一个接口多个实现
        //builder.RegisterType<TestRepository>().As<ITestRepository>().Named<ITestRepository>("TestRepository").AsSelf().InstancePerLifetimeScope().PropertiesAutowired();
        
        //base.Load(builder);
    }
}
